package com.pricl.frame.core.web;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.context.WebApplicationContext;

import com.pricl.frame.cache.MyRedisConfig;
import com.pricl.frame.core.E;
import com.pricl.frame.core.User;

import redis.clients.jedis.JedisPoolConfig;

/**
 * 
 * @author cheng(iknoweth@yahoo.com)
 * @date 2016-5-4 下午10:17:47
 */
public class Helper extends PropertyPlaceholderConfigurer implements ApplicationContextAware {

	private static ApplicationContext context;

	private static Map<String, String> props = new HashMap<String, String>();

	public static String webRoot;

	private static Map<String, Object> currentUsers = new HashMap<>();
	
	private static RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
	
	private static String USER_SESSION_KEY = "USER:";

	//TODO 性能提升 使用redis保存用户对象
	public static void setUser(String sid, User user) {
		currentUsers.put(sid, user);
	}

	/**
	 * 根据session id 获取登录用户信息
	 * @param sid
	 * @return
	 */
	public static User getUser(String sid) {
		Object object = currentUsers.get(sid);
		if (object == null) {
			object = redisTemplate.opsForValue().get("User"+sid);
			if (object == null) {
				throw new E("Helper -->请重新登陆");
			}
		}
		return (User) object;
		// return (User) currentUsers.get(sid);
	}

	/**
	 * 获取当前登录用户信息
	 * @return
	 */
	public static User getCurrentUser() {
		Session session=SecurityUtils.getSubject().getSession();
		if(session!=null){
			Object object = currentUsers.get(session.getId());
			if (object == null) {
				// add by winton 2017-9-21 如果全局变量不存在，就在缓存里面获取
				object = redisTemplate.opsForValue().get(USER_SESSION_KEY+session.getId());
				if (object == null) {
					throw new E("Helper>请重新登陆");
				}
			}
			// 如果不为空，就先清空之前该用户的session用户缓存。然后插入redis
			try {
				redisTemplate.delete(USER_SESSION_KEY+session.getId());
			} catch(E e) {
				e.printStackTrace();
			}
			redisTemplate.opsForValue().set(USER_SESSION_KEY+session.getId(), (User)object);
			return (User) object;
		}
		if(session==null) System.out.println("================================================================session==null");
		return null;
	}


	public static User removeUser(String sid) {
		return (User) currentUsers.remove(sid);
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		Helper.setApplicationContext0(applicationContext);

		// add by winton 2017-9-21
		// 框架搭建导致用redis做session缓存的时候，重启服务后丢失了Helper类的全局currentUsers。导致部分功能不能使用。
		// TODO 待优化：context可以直接取得bean，但是需要加载properties文件。
		
		// jedisfactory
		JedisConnectionFactory jcf = new JedisConnectionFactory();
		jcf.setDatabase(Integer.valueOf(MyRedisConfig.getInstance().getDatabase()));
		jcf.setHostName(MyRedisConfig.getInstance().getHost());
		jcf.setPassword(MyRedisConfig.getInstance().getPassword());
		
		// poolconfig
		JedisPoolConfig jp = new JedisPoolConfig();
		jp.setMaxIdle(Integer.valueOf(MyRedisConfig.getInstance().getMaxIdle()));
		jp.setMaxWaitMillis(Long.valueOf(MyRedisConfig.getInstance().getMaxWaitMillis()));
		jp.setTestOnBorrow(Boolean.valueOf(MyRedisConfig.getInstance().getTestOnBorrow()));
		
		jcf.setPoolConfig(jp);
		jcf.setUsePool(true);
		// 初始化工厂默认配置
		jcf.afterPropertiesSet();
		redisTemplate.setConnectionFactory(jcf);
		// 初始化template默认配置
		redisTemplate.afterPropertiesSet();
	}

	public static ApplicationContext getApplicationContext() {
		return context;
	}

	private static void setApplicationContext0(ApplicationContext applicationContext) {
		if (applicationContext != null && applicationContext instanceof WebApplicationContext) {
			webRoot = ((WebApplicationContext) applicationContext).getServletContext().getRealPath("/");
		}
		Helper.context = applicationContext;
	}

	/**
	 * <p>
	 * 例如SnsUser.class
	 * </p>
	 * 
	 * @param clazz
	 * @return
	 */
	public static <T> T getBean(Class<T> clazz) {
		return context.getBean(clazz);
	}

	/**
	 * <p>
	 * snsUser 传入的是bean的别名 如果未定义别名 类首字母小写
	 * </p>
	 * 
	 * @param name
	 * @return
	 */
	public static Object getBean(String name) {
		return context.getBean(name);
	}

	@Override
	protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props)
			throws BeansException {
		for (Object key : props.keySet()) {
			Helper.props.put(key.toString(), props.get(key).toString());
		}
		super.processProperties(beanFactoryToProcess, props);
	}

	public static String getProp(String key) {
		return props.get(key);
	}

	public static String getProp(String key, String defaultValue) {
		String v = getProp(key);
		if (v == null) {
			return defaultValue;
		}
		return v;
	}
}
